// 接口的兼容性, ts跟类型没有关系，只跟属性有关系
namespace a {
  interface Animal {
    name: string;
    age: number;
  }
  interface Person {
    name: string;
    age: number;
    speak: (words: string) => void
  }
  function getName(animal: Animal): string {
    return animal.name;
  }
  let a: Animal = {
    name: 'lei',
    age: 20,
  }
  let p = {
    name: 'wu',
    age: 27,
    speak() {
      console.log('speak');
    }
  }
  // 按理说这个getName方法接受一个animal对象实例，但是实际上这里传入一个Person对象也可以，
  // 只要name属性就可以
  console.log(getName(p));
  console.log(getName(a));
  // 基本类型的兼容性
  let num: string | number; // 具体类型会随着后面的变化而变化
  let str: string;
  num = 12;
  num = '111'


  let num2: { // num2是一个有toString方法的对象
    toString(): string
  }
  let str2:string = 'aaa'
  num2 = str2
  num2 = 12

}
namespace b {
  // 类的兼容性 跟类型无关,只要`有我要的属性就行`
  class Animal {
    name:string;
  }
  class Bird extends Animal {
    // swing:string
  }
  let a:Animal;
  a = new Bird() // 跟类型无关，只要Bird中有name属性即可
  let b:Bird;
  b = new Animal() // 这样也行
  let c = {name: 'asa'}
  b = c // 也能赋值给b实例，因为c中有name属性
  // a = {name: 'ss',age:23} // Animal实例中没有age属性，`所以报错`
}
namespace c {
  // 函数的兼容性
}